﻿using System;
using System.Reflection;
using System.Collections.Generic;

using AnB.Common;

namespace AnB.Net
{
    public abstract class CmdHandler
    {
        public ushort Cmd;
        public string Name;
        public Type In;
        public Type Out;
        public long SizeLimit;

        public Packet.BodyType InBody;
        public Packet.BodyType OutBody;
        public string Description;

        public abstract object Handle(Connection connection, object _in);
        public abstract void Prepare();
    }

    public abstract class MethodCmdHandler : CmdHandler
    {
        protected MethodBase mMethod;
        public override object Handle(Connection connection, object _in)
        {
            return mMethod.Invoke(null, new object[] { connection, _in });
        }
    }
    public class TypeMethodCmdHandler : MethodCmdHandler
    {
        public TypeMethodCmdHandler(string namespace_)
        {
            mNamespaces = new string[] { namespace_ };
        }
        public TypeMethodCmdHandler(IEnumerable<string> namespaces)
        {
            mNamespaces = namespaces;
        }
        private IEnumerable<string> mNamespaces;
        public override void Prepare()
        {
            var splits = Name.Split('.');
            if (splits.Length != 2)
            {
                throw new Exception(string.Format("{0} invalid <class>.<method> format", Description));
            }
            var type = Utils.GetType(splits[0], mNamespaces);
            mMethod = type.GetMethod(splits[1], BindingFlags.Static | BindingFlags.Public);
        }
    }
}
